<template>
  <div>
    <a-layout class="chat-page">
      <a-layout-sider width="280px" class="chat-list-box">
        <div class="chat-list-header">
          <a-input-search placeholder="搜索" v-model="friendQueryParam.name" allow-clear @keyup.enter.native="handleQuery" @search="handleQuery" enter-button />
        </div>
        <div>
          <a-list>
            <RecycleScroller ref="friendScroll" v-infinite-scroll="handleInfiniteOnLoad" style="height: 500px" :items="friendList" :item-size="73" key-field="user" :infinite-scroll-disabled="friendBusy" :infinite-scroll-distance="10">
              <a-list-item slot-scope="{ item }" class="friend" @click="chooseUser(item)">
                <a-list-item-meta>
                  <p slot="description" class="text-1-line">{{ item.message.content }}</p>
                  <a slot="title">{{ item.user.name }}</a>
                  <a-avatar slot="avatar" shape="square" size="large" :src="imageUrl + item.user.avatar" alt="image" />
                </a-list-item-meta>
                <div>{{ item.message.createTime ? toTimeText(item.message.createTime, true) : '' }}</div>
              </a-list-item>
            </RecycleScroller>
            <a-spin v-if="friendLoading" />
          </a-list>
        </div>
      </a-layout-sider>
      <a-layout v-if="toUser != null">
        <a-layout-header class="msg-head">
          {{ toUser.name }}
        </a-layout-header>
        <a-layout-content>
          <div ref="scrollDiv" v-infinite-scroll="messageInfiniteOnLoad" infinite-scroll-distance="10" :infinite-scroll-disabled="busy" :infinite-scroll-immediate-check="false" style="height: 350px; overflow: auto">
            <a-list item-layout="vertical" :data-source="historyMessage" :split="false">
              <a-list-item slot="renderItem" slot-scope="item">
                <div class="chat-msg-tip" v-if="item.createTime !== ''">
                  {{ toTimeText(item.createTime) }}
                </div>
                <a-list-item-meta>
                  <message-item slot="description" :message="item" :mine="item.fromId == user.id">
                    <template v-if="item.fromId == user.id" slot="mine-avatar">
                      <a-avatar class="msg-avatar-mine" shape="square" :size="48" :src="imageUrl + user.avatar" alt="image" />
                    </template>
                  </message-item>
                  <a-avatar class="msg-avatar" v-if="item.fromId != user.id" slot="avatar" shape="square" :size="48" :src="imageUrl + toUser.avatar" alt="image" />
                </a-list-item-meta>
              </a-list-item>
            </a-list>
          </div>
          <div class="chat-box">
            <a-textarea v-model="message.content" :autoSize="{ minRows: 8, maxRows: 8 }" />
            <div class="send-btn-area">
              <a-button type="primary" :disabled="sendDisabled" @click="send">发送</a-button>
            </div>
          </div>
        </a-layout-content>
      </a-layout>
      <a-empty style="margin: auto" v-else description="暂无消息" />
    </a-layout>
  </div>
</template>

<script>
import { getInitData, sendMessage, getUserMessageList, getLastMessageList } from '@/api/platform/message'
import { getUserProfile, getUser } from '@/api/system/user'
import { getUserRecordByOnlineUser } from '@/api/platform/userRecord'
import MessageItem from '@/views/platform/components/MessageItem.vue'
import { toTimeText } from '@/utils/util.js'
export default {
  name: 'Chat',
  components: {
    MessageItem
  },
  data() {
    return {
      //图片链接
      imageUrl: process.env.VUE_APP_BASE_API,
      user: null,
      webSocket: null,
      historyMessage: [],
      friendQueryParam: {
        pageNum: 1,
        pageSize: 10,
        name: undefined
      },
      friendList: [],
      friendTotal: 0,
      friendLoading: false,
      friendBusy: false,
      toUser: null,
      message: {
        id: undefined,
        fromId: undefined,
        toId: undefined,
        content: '',
        type: '0',
        status: '0'
      },
      messageQueryParam: {
        toId: undefined
      },
      //RegisterMessage
      registerMessage: { fromId: '', type: 'REGISTER', content: undefined },
      //HeaterMessage
      heartMessage: { fromId: '', type: 'HEARTBEAT' },
      sendDisabled: true,
      sendTime: new Date(),
      busy: true
    }
  },

  watch: {
    'message.content': {
      handler(newval) {
        if (newval) {
          this.sendDisabled = false
        } else {
          this.sendDisabled = true
        }
      }
    }
  },
  created() {
    getUserProfile().then(response => {
      this.user = response.data.user
      //设置注册包、心跳包、TextMessage的UserId
      this.registerMessage.fromId = this.heartMessage.fromId = this.user.id
      this.webSocket = new WebSocket('ws://localhost:8878/websocket')
      this.initWebSocket()
    })
    this.getFriendList()
  },
  computed: {},
  methods: {
    //判断时间是否超一分钟
    getChatTime(previousTimeString, nextTimeString) {
      const previousTime = new Date(previousTimeString)
      const nextTime = new Date(nextTimeString)
      const oneMinute = 60000 // 60 * 1000ms
      const difference = Math.abs(previousTime.getTime() - nextTime.getTime())
      return difference < oneMinute
    },
    toTimeText,
    initWebSocket() {
      // 连接成功
      this.webSocket.onopen = this.onOpen
    },
    onOpen() {
      //向服务器发送注册消息
      getUserRecordByOnlineUser().then(res => {
        if (res.data) {
          this.registerMessage.content = res.data.regionId
        }
        this.webSocket.send(JSON.stringify(this.registerMessage))
      })
      this.webSocket.addEventListener('message', this.handleWsMessage.bind(this), false)
      //发送心跳包
      setInterval(() => {
        this.webSocket.send(JSON.stringify(this.heartMessage))
      }, 3000)
    },

    handleWsMessage(response) {
      const res = JSON.parse(response.data)
      if (res.type === '0') {
        const sendMessage = JSON.parse(res.content)
        const index = this.friendList.findIndex(item => item.user.id === sendMessage.fromId)
        if (index !== -1) {
          const sendUser = this.friendList[index].user
          this.friendList.splice(index, 1)
          this.friendList.unshift({ user: sendUser, message: sendMessage })
        } else {
          getUser(sendMessage.fromId).then(response => {
            this.friendList.unshift({ user: response.data, message: sendMessage })
          })
        }
        this.handleScrollTop()
        if (this.user.id !== sendMessage.fromId) {
          this.historyMessage.push(sendMessage)
          if (this.toUser) {
            this.handleScrollBottom()
          }
        }
      }
    },

    /** 搜索按钮操作 */
    handleQuery() {
      this.friendQueryParam.pageNum = 1
      this.friendList = []
      this.getFriendList()
    },
    messageInfiniteOnLoad() {
      this.busy = true
      getLastMessageList(this.messageQueryParam).then(response => {
        const messageList = JSON.parse(JSON.stringify(response.data.rows))
        this.historyMessage = messageList.map((item, index) => {
          if (index > 0 && this.getChatTime(response.data.rows[index - 1].createTime, item.createTime)) {
            item.createTime = ''
          }
          return item
        })
        this.busy = false
        this.handleScrollBottom()
      })
    },
    handleInfiniteOnLoad() {
      if (this.friendQueryParam.pageNum <= this.friendTotal / this.friendQueryParam.pageSize) {
        this.friendLoading = true
        this.friendBusy = true
        this.friendQueryParam.pageNum++
        getUserMessageList(this.friendQueryParam).then(response => {
          const that = this
          const index = response.data.rows.findIndex(item => {
            const i = item
            const f = that.friendList.find(frined => {
              return frined.user.id === i.user.id
            })
            if (f) {
              return item.user.id === f.user.id
            }
          })
          if (index != -1) response.data.rows.splice(index, 1)
          this.friendList.push(...response.data.rows)
          this.friendLoading = false
          this.friendBusy = false
        })
      }
    },
    getFriendList() {
      getUserMessageList(this.friendQueryParam).then(response => {
        this.friendList = response.data.rows
        this.friendTotal = response.data.total
      })
    },

    chooseUser(item) {
      this.toUser = item.user
      this.messageQueryParam.toId = this.toUser.id
      this.historyMessage = []
      this.messageInfiniteOnLoad()
    },

    send() {
      this.message.fromId = this.user.id
      this.message.toId = this.toUser.id
      sendMessage(this.message).then(response => {
        if (this.historyMessage.length > 0) {
          if (this.historyMessage[this.historyMessage.length - 1].createTime !== '') {
            this.sendTime = this.historyMessage[this.historyMessage.length - 1].createTime
          }
          if (this.getChatTime(this.sendTime, response.data.createTime)) {
            this.sendTime = response.data.createTime
            response.data.createTime = ''
          }
        }
        this.historyMessage.push(response.data)
        const index = this.friendList.findIndex(item => item.user.id === this.toUser.id)
        this.friendList.splice(index, 1)
        this.friendList.unshift({ user: this.toUser, message: response.data })
        this.message.content = ''
        this.handleScrollBottom()
        this.handleScrollTop()
      })
    },
    // 滚动到顶部
    handleScrollTop() {
      this.$nextTick(() => {
        const scrollElem = this.$refs.friendScroll
        scrollElem.scrollToItem(0)
      })
    },
    // 滚动到底部
    handleScrollBottom() {
      this.$nextTick(() => {
        const scrollElem = this.$refs.scrollDiv
        scrollElem.scrollTo({ top: scrollElem.scrollHeight, behavior: 'smooth' })
      })
    }
  }
}
</script>

<style lang="less" scoped>
.chat-page {
  .chat-msg-tip {
    display: flex;
    justify-content: center; /* 水平居中 */
    align-items: center; /* 垂直居中 */
    font-size: 14px;
  }
  .chat-list-box {
    display: flex;
    flex-direction: column;
    border: #dddddd solid 1px;
    background: white;
    width: 3rem;

    .chat-list-header {
      padding: 5px;
      background-color: white;
      line-height: 50px;
    }
  }
}
.friend {
  padding: 10px;
  &:hover {
    background-color: #eeeeee;
  }

  &.active {
    background-color: #e8e8f0;
  }
}
.text-1-line {
  width: 130px;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

.msg-head {
  font-size: 18px;
  text-align: center;
  font-weight: 600;
}

.msg-avatar {
  margin-left: 20px;
  margin-top: 10px;
}
.msg-avatar-mine {
  position: absolute;
  left: auto;
  right: 15;
}
.chat-box {
  position: relative;
  width: 100%;
  background: #f8f8f8;
  border: #dddddd solid 1px;
  .send-btn-area {
    padding: 10px;
    position: absolute;
    bottom: 0;
    right: 0;
  }
}
</style>
